﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Xml;
using System.IO;
using System.Data;
using System.Xml.Linq;

namespace KXCXW.Web.CommonClass
{
    /// <summary>
    /// XML帮助类
    /// </summary>
    public sealed class XmlHelper
    {
         #region fields

        private string fileName = string.Empty;


        //private XmlDocument doc = new XmlDocument();

        #endregion

        #region property

        /// <summary>
        /// xml文件名称，如a.config;b.xml
        /// </summary>
        public string FileName
        {
            get
            {
                return this.fileName;
            }
            set
            {
                this.fileName = value;
            }
        }

        #endregion

        #region 解析XML文本
        /// <summary>
        /// 获取XML文本中的指定元素的内容
        /// </summary>
        /// <param name="xmlString">XML文本</param>
        /// <param name="elemName">元素名</param>
        /// <returns></returns>
        public static string GetElemContent(string xmlString, string elemName)
        {
            if (string.IsNullOrEmpty(xmlString))
            {
                return string.Empty;
            }
            XElement x = XElement.Parse(xmlString);
            if (x == null || x.Elements().Count()<1)
            {
                return string.Empty;
            }

            return x.Elements(elemName).First().Value;
        }

        #endregion

        #region methods

        public XmlHelper(string fileName)
        {
            this.FileName = fileName;
        }

        /// <summary>
        /// 返回第一个找到的元素里面的值，包含标记和子元素
        /// </summary>
        /// <param name="xPath"></param>
        /// <returns></returns>
        public string Get(string xPath)
        {
            XmlDocument doc = new XmlDocument();
            doc.Load(this.FileName);
            XmlNode node = doc.SelectSingleNode(xPath);
            if (node != null)
            {
                return node.InnerXml;

            }
            return string.Empty;
        }


        /// <summary>
        /// 用新的XML文件更新旧的XML文件
        /// 仅更新第一层节点
        /// </summary>
        /// <param name="newFile"></param>
        /// <param name="oldFile"></param>
        /// <param name="onlyUpdateNodeName">仅更新节点名称,否则全部更新</param>
        /// <returns></returns>
        public static  int UpdateXml(string newFile, string oldFile,bool onlyUpdateNodeName)
        {
            //仅更新节点
            if (onlyUpdateNodeName )
            {
                XElement xNew = XElement.Load(newFile);
                XElement xOld = XElement.Load(oldFile);

                #region 修改xNew中节点值
                IEnumerable<XElement> eCol = xOld.Elements();
                foreach (XElement subElem in eCol)
                {
                    if (xNew.Element(subElem.Name) != null)
                    {
                        xNew.Element(subElem.Name).Value = subElem.Value;
                    }
                }//foreach
                #endregion

                xNew.Save(oldFile);

            }
            else
            {
                File.Copy(newFile, oldFile, true);
                return 1;
            }//if

            return 1;
        }

        /// <summary>
        /// 获取子节点列表
        /// </summary>
        /// <param name="xpath"></param>
        /// <returns></returns>
        public XmlNodeList GetSubNodes(string xpath)
        {
            XmlDocument doc = new XmlDocument();
            doc.Load(this.FileName);
            return doc.SelectNodes(xpath);
        }

        /// <summary>
        /// 返回第一个找到的元素中属性的值
        /// </summary>
        /// <param name="xPath"></param>
        /// <param name="attrName"></param>
        /// <returns></returns>
        public string Get(string xPath, string attrName)
        {
            XmlDocument doc = new XmlDocument();
            doc.Load(this.FileName);
            XmlNode node = doc.SelectSingleNode(xPath);
            if (node != null && node.Attributes[attrName] != null)
            {
                return node.Attributes[attrName].Value;
            }
            return string.Empty;
        }

        public List<string> GetValues(string xPath, string attrName)
        {
            XmlDocument doc = new XmlDocument();
            doc.Load(this.FileName);
            XmlNodeList nodeList = doc.SelectNodes(xPath);

            List<string> lsValue = new List<string>();
            foreach (XmlNode node in nodeList)
            {
                lsValue.Add(node.Attributes[attrName].Value);
            }

            return lsValue ;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="xPath"></param>
        /// <param name="nodeValue"></param>
        public void Set(string xPath, string nodeValue)
        {
            XmlDocument doc = new XmlDocument();
            doc.Load(this.FileName);
            XmlNode node = doc.SelectSingleNode(xPath);
            if (node != null)
            {
                node.InnerXml = nodeValue;
            }
            doc.Save(this.FileName);
        }

        /// <summary>
        /// 返回第一个找到的元素中属性的值
        /// </summary>
        /// <param name="xPath"></param>
        /// <param name="attrName"></param>
        /// <param name="attrValue"></param>
        public void Set(string xPath, string attrName, string attrValue)
        {
            XmlDocument doc = new XmlDocument();
            doc.Load(this.FileName);
            XmlNode node = doc.SelectSingleNode(xPath);
            if (node != null && node.Attributes[attrName] != null)
            {
                node.Attributes[attrName].Value = attrValue;
            }
            doc.Save(this.FileName);
        }

        /// <summary>
        /// 判断符合xpath条件的节点是否存在
        /// </summary>
        /// <param name="xPath"></param>
        /// <returns></returns>
        public bool IsExists(string xPath)
        {
            XmlDocument doc = new XmlDocument();
            doc.Load(this.FileName);
            XmlNode node = doc.SelectSingleNode(xPath);
            if (node != null)
            {
                return true;
            }
            return false;
        }



        /// <summary>
        /// 
        /// </summary>
        /// <param name="parentNodeXPath"></param>
        /// <param name="subNodeName">子节点名称</param>
        /// <param name="subAttrName">子节点属性名称</param>
        /// <param name="subAttrValue">子节点属性值</param>
        public void AddSubNode(string parentNodeXPath, string subNodeName, string subAttrName, string subAttrValue)
        {
            XmlDocument doc = new XmlDocument();
            doc.Load(this.FileName);
            XmlNode parentNode = doc.SelectSingleNode(parentNodeXPath);

            XmlElement subElem = doc.CreateElement(subNodeName);
            XmlAttribute attrName = doc.CreateAttribute(subAttrName);
            attrName.Value = subAttrValue;
            subElem.Attributes.Append(attrName);

            parentNode.AppendChild(subElem);
            doc.Save(this.FileName);

        }

        public void AddSubNode(string parentNodeXPath, string innerXml)
        {
            XmlDocument doc = new XmlDocument();
            doc.Load(this.FileName);
            XmlNode parentNode = doc.SelectSingleNode(parentNodeXPath);
            parentNode.InnerXml = innerXml;
            doc.Save(this.FileName);

        }


        #endregion


        #region XML 和 DataSet,DataTable互换

        public sealed  class XmlToData
        {
            /**/
            /// <summary>
            /// 将Xml内容字符串转换成DataSet对象
            /// </summary>
            /// <param name="xmlStr">Xml内容字符串</param>
            /// <returns>DataSet对象</returns>
            public static DataSet CXmlToDataSet(string xmlStr)
            {
                if (!string.IsNullOrEmpty(xmlStr))
                {
                    StringReader StrStream = null;
                    XmlTextReader Xmlrdr = null;
                    try
                    {
                        DataSet ds = new DataSet();
                        //读取字符串中的信息
                        StrStream = new StringReader(xmlStr);
                        //获取StrStream中的数据
                        Xmlrdr = new XmlTextReader(StrStream);
                        //ds获取Xmlrdr中的数据                
                        ds.ReadXml(Xmlrdr);
                        return ds;
                    }
                    catch (Exception e)
                    {
                        throw e;
                    }
                    finally
                    {
                        //释放资源
                        if (Xmlrdr != null)
                        {
                            Xmlrdr.Close();
                            StrStream.Close();
                            StrStream.Dispose();
                        }
                    }
                }
                else
                {
                    return null;
                }
            }
            /**/
            /// <summary>
            /// 将Xml字符串转换成DataTable对象
            /// </summary>
            /// <param name="xmlStr">Xml字符串</param>
            /// <param name="tableIndex">Table表索引</param>
            /// <returns>DataTable对象</returns>
            public static DataTable CXmlToDatatTable(string xmlStr, int tableIndex)
            {
                return CXmlToDataSet(xmlStr).Tables[tableIndex];
            }
            /**/
            /// <summary>
            /// 将Xml字符串转换成DataTable对象
            /// </summary>
            /// <param name="xmlStr">Xml字符串</param>
            /// <returns>DataTable对象</returns>
            public static DataTable CXmlToDatatTable(string xmlStr)
            {
                return CXmlToDataSet(xmlStr).Tables[0];
            }
            /**/
            /// <summary>
            /// 读取Xml文件信息,并转换成DataSet对象
            /// </summary>
            /// <remarks>
            /// DataSet ds = new DataSet();
            /// ds = CXmlFileToDataSet("/XML/upload.xml");
            /// </remarks>
            /// <param name="xmlFilePath">Xml文件地址</param>
            /// <returns>DataSet对象</returns>
            public static DataSet CXmlFileToDataSet(string xmlFilePath)
            {
                if (!string.IsNullOrEmpty(xmlFilePath))
                {
                    //string path = HttpContext.Current.Server.MapPath(xmlFilePath);
                    string path = xmlFilePath;
                    StringReader StrStream = null;
                    XmlTextReader Xmlrdr = null;
                    try
                    {
                        XmlDocument xmldoc = new XmlDocument();
                        //根据地址加载Xml文件
                        xmldoc.Load(path);

                        DataSet ds = new DataSet();
                        //读取文件中的字符流
                        StrStream = new StringReader(xmldoc.InnerXml);
                        //获取StrStream中的数据
                        Xmlrdr = new XmlTextReader(StrStream);
                        //ds获取Xmlrdr中的数据
                        ds.ReadXml(Xmlrdr);
                        return ds;
                    }
                    catch (Exception e)
                    {
                        throw e;
                    }
                    finally
                    {
                        //释放资源
                        if (Xmlrdr != null)
                        {
                            Xmlrdr.Close();
                            StrStream.Close();
                            StrStream.Dispose();
                        }
                    }
                }
                else
                {
                    return null;
                }
            }
            /**/
            /// <summary>
            /// 读取Xml文件信息,并转换成DataTable对象
            /// </summary>
            /// <param name="xmlFilePath">xml文江路径</param>
            /// <param name="tableIndex">Table索引</param>
            /// <returns>DataTable对象</returns>
            public static DataTable CXmlToDataTable(string xmlFilePath, int tableIndex)
            {
                return CXmlFileToDataSet(xmlFilePath).Tables[tableIndex];
            }
            /**/
            /// <summary>
            /// 读取Xml文件信息,并转换成DataTable对象
            /// </summary>
            /// <param name="xmlFilePath">xml文江路径</param>
            /// <returns>DataTable对象</returns>
            public static DataTable CXmlToDataTable(string xmlFilePath)
            {
                return CXmlFileToDataSet(xmlFilePath).Tables[0];
            }
        }
        #endregion
    }
}